#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
#include <queue>
#include <algorithm>
#define REP(i,n) for(int i=0;i<int(n);++i)
using namespace std;
const int inf = 1<<29;
typedef pair<int,int> pii;
struct Edge
{
    int vs,vt,flow,cap;
    Edge *next;
    void set(int a,int b,int w)
    {
    	vs=a,vt=b,cap=w;
    	flow=0;
    }
};
int n,t;
class Graph
{
    static const int MVN=20200,MARCN= 200200*4+MVN*4;
public:
    int vn,arcn;
    Edge *edge,*head[MVN];
    Graph(int n=0)
    {
        init(n);
        edge=new Edge[MARCN];
    };
    void init(int n)
    {
        vn=n;
        arcn=0;
        fill(head,head+n+1,(Edge*)NULL);
    }
    void add(int vs,int vt,int cap)
    {
        edge[arcn].set(vs,vt,cap);
        edge[arcn].next=head[vs];
        head[vs]=&edge[arcn++];
    }
    void addEdge(int vs,int vt,int cap)
    {
    	add(vs,vt,cap);
    	add(vt,vs,0);
    }
    int maxFlow(int vs,int vt)
    {
        int dist[MVN],cnt[MVN],ans=0;
        Edge *pre[MVN],*cur[MVN];
        for(int i=0;i<=vn;i++)
        {
        	cnt[i]=dist[i]=0;
        	pre[i]=NULL;
        	cur[i]=head[i];
        }
        cnt[0]=vn;
        int pos=vs;
        Edge *ep;
        while (dist[vs]<vn)
        {
        	for(ep=cur[pos];ep;ep=ep->next) if(dist[pos]==dist[ep->vt]+1&&ep->cap-ep->flow) break;
        	if(ep)
        	{
        		cur[pos]=ep; pre[ep->vt] = ep;
        		pos=ep->vt;
        		if(pos==vt)
        		{
        			int minf=inf;
        			for(ep=pre[vt];ep;ep=pre[ep->vs]) if(ep->cap-ep->flow<minf)
        			{
        				minf=ep->cap-ep->flow;
        				pos=ep->vs;
        			}
        			for(ep=pre[vt];ep;ep=pre[ep->vs])
        			{
        				ep->flow+=minf;
        				edge[(ep-edge)^1].flow-=minf;
        			}
        			ans+=minf;
        		}
        	}
        	else
        	{
        		if(--cnt[dist[pos]]==0) break;
        		dist[pos]=vn;
        		for(ep=head[pos];ep;ep=ep->next) if(dist[pos]>dist[ep->vt]+1&&ep->cap-ep->flow>0)
        			dist[pos]=dist[ep->vt]+1,cur[pos]=ep;
				cnt[dist[pos]]++;
				if(pos!=vs) pos=pre[pos]->vs;
        	}
        }
        return ans;
    }
};

char map[15][15];
char resq[15][15];
int dist1[15][15];
int dist2[15][15];
int dir[][2]={{0,1},{0,-1},{1,0},{-1,0}};
int ss,tt;
Graph g;
inline int getV(int x,int y)
{
    return x*n+y;
}
void getDist1()
{
    REP(i,n) REP(j,n) dist1[i][j]=inf;
    queue<pii> q;
    REP(i,n) REP(j,n) if(map[i][j]=='Z')
    {
        q.push(pii(i,j));
        dist1[i][j]=0;
        break;
    }
    while(!q.empty())
    {
        int x=q.front().first,y=q.front().second;
        q.pop();
        if(dist1[x][y]+1>t) return;
        REP(i,4)
        {
            int tx=x+dir[i][0],ty=y+dir[i][1];
            if(tx<0||tx>=n||ty<0||ty>=n) continue;
            else if(dist1[x][y]+1<dist1[tx][ty]&&map[tx][ty]!='Y'&&map[tx][ty]!='Z')
            {
                dist1[tx][ty]=dist1[x][y]+1;
                q.push(pii(tx,ty));
            }
        }
    }
}
void getDist2(int px,int py)
{
    REP(i,n) REP(j,n) dist2[i][j]=inf;
    queue<pii> q;
    q.push(pii(px,py));
    dist2[px][py]=0;
    g.addEdge(getV(px,py),getV(px,py)+n*n,inf);
    while(!q.empty())
    {
        int x=q.front().first,y=q.front().second;
        q.pop();
        if(dist2[x][y]+1> t) return;
        REP(i,4)
        {
            int tx=x+dir[i][0],ty=y+dir[i][1];
            if(tx<0||tx>=n||ty<0||ty>=n) continue;
            else if(dist2[x][y]+1<dist2[tx][ty]
                &&dist2[x][y]+1<=dist1[tx][ty]
                &&map[tx][ty]!='Y'&&map[tx][ty]!='Z')
            {
                dist2[tx][ty]=dist2[x][y]+1;
                if(dist2[tx][ty]<dist1[tx][ty]) q.push(pii(tx,ty));
                int f=resq[tx][ty]-'0';
                g.addEdge(getV(px,py),getV(tx,ty)+n*n,inf);
            }
        }
    }
}
int main()
{
    cin>>n>>t;
    g.init(n*n*2+10);
    ss=n*n*2+4,tt=ss+1;
    REP(i,n) scanf("%s",map[i]);
    REP(i,n) scanf("%s",resq[i]);
    getDist1();
    REP(i,n) REP(j,n) if(map[i][j]>='0'&&map[i][j]<='9')
        getDist2(i,j);
    REP(i,n) REP(j,n) if(map[i][j]>='0'&&map[i][j]<='9')
    {
        g.addEdge(ss,getV(i,j),map[i][j]-'0');
        g.addEdge(getV(i,j)+n*n,tt,resq[i][j]-'0');
    }
    cout<<g.maxFlow(ss,tt)<<endl;
	return 0;
}
